package com.ellfors.common.base

import android.graphics.Rect
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.ViewGroup
import android.widget.EditText
import android.widget.FrameLayout
import androidx.core.view.isVisible
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.ellfors.common.ext.hideKeyboard
import com.ellfors.common.ext.observe
import com.ellfors.common.ext.toast
import com.ellfors.common.widget.LoadingView
import java.lang.reflect.ParameterizedType

/**
 * View的继承这个
 *
 * @param VB ViewBinding类
 * @param VM ViewModel类 没有就传[EmptyViewModel]
 */
@Suppress("UNCHECKED_CAST")
abstract class BaseActivity<VB : ViewBinding, VM : BaseViewModel> : BaseAndroidActivity() {

    private val _binding by lazy {
        buildViewBinding()
    }
    private val _viewModel by lazy {
        buildViewModel()
    }
    private val _titleBar by lazy {
        BaseTitleBar(this)
    }
    private val _loadingView by lazy {
        LoadingView(this).apply {
            setCanceledOnTouchOutside(false)
        }
    }

    // 是否允许点击EditText外部隐藏软键盘，默认允许
    private var _isKeyboardHideOnTouchOutside = true

    val mBinding: VB
        get() = _binding
    val mViewModel: VM
        get() = _viewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(_binding.root)

        initView()
        initData()
        observerData()
    }

    override fun onDestroy() {
        super.onDestroy()
        dismissLoading()
    }

    abstract fun initView()

    private fun observerData() {
        _viewModel.isLoading.observe(this) {
            //开启关闭loading
        }
        _viewModel.httpResult.observe(this) {
            if (it.first) {
                handleHttpSuccess(it.second)
            } else {
                handleHttpError(it.second, it.third)
            }
        }
    }

    private fun buildViewBinding(): VB {
        val superClass = javaClass.genericSuperclass as ParameterizedType
        val vbClass = superClass.actualTypeArguments[0] as Class<VB>
        val method = vbClass.getMethod("inflate", LayoutInflater::class.java)
        return method.invoke(null, layoutInflater) as VB
    }

    private fun buildViewModel(): VM {
        val superClass = javaClass.genericSuperclass as ParameterizedType
        val vmClass = (superClass.actualTypeArguments[1] as Class<VM>).kotlin
        return ViewModelProvider(this, ViewModelProvider.NewInstanceFactory())[vmClass.java]
    }


    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event?.action == MotionEvent.ACTION_DOWN) {
            val view = currentFocus
            if (view is EditText) {
                val outRect = Rect()
                view.getGlobalVisibleRect(outRect)
                if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                    if (_isKeyboardHideOnTouchOutside) {
                        hideKeyboard()
                    }
                }
            }
        }
        return super.onTouchEvent(event)
    }

    /**
     * 处理http请求成功
     */
    open fun handleHttpSuccess(code: Int) {

    }

    /**
     * 处理http请求失败
     */
    open fun handleHttpError(code: Int, msg: String) {
        msg.toast()
    }

    /**
     * 是否允许点击EditText外部隐藏软键盘
     */
    open fun allowKeyboardHideOnTouchOutside(flag: Boolean) {
        _isKeyboardHideOnTouchOutside = flag
    }

    /**
     * 显示Loading
     */
    fun showLoading() {
        _loadingView.show()
    }

    /**
     * 隐藏Loading
     */
    fun dismissLoading() {
        _loadingView.dismiss()
    }

    /*
     ********************* Title Bar ********************************
     */

    override fun showTitleBar(title: String) {
        val contentView = findViewById<FrameLayout>(android.R.id.content)
        val firstChildView = contentView?.getChildAt(0)
        val params = firstChildView?.layoutParams as ViewGroup.MarginLayoutParams?
        params?.topMargin = BaseTitleBar.TITLE_BAR_HEIGHT
        firstChildView?.layoutParams = params
        contentView?.addView(
            _titleBar, 0, FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, BaseTitleBar.TITLE_BAR_HEIGHT
            )
        )
        _titleBar.setTitle(title)
        _titleBar.isVisible = true
    }

    override fun hideTitleBar() {
        _titleBar.isVisible = false
    }

    override fun hideTitleBarClose() {
        _titleBar.switchCloseVisible(false)
    }

    override fun setTitleBarBackListener(block: () -> Unit) {
        _titleBar.setOnBackClickListener {
            block()
        }
    }
}